#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#define MAX_ENV 100
#define MAXARGC 128
char *g_argv[MAXARGC];
int g_argc = 0;

#define COMMAND_SIZE 1024
#define FORMAT "[%s@%s %s]# "
const char *GetUserName()
{
  const char *name = getenv("USER");
  return name == NULL ? "None" : name;
}
const char *GetHostName()
{
  const char *hostname = getenv("HOSTNAME");
  return hostname ==  NULL ? "None" : hostname;
}

const char *GetPwd()
{
  const char *pwd = getenv("PWD");
  return pwd == NULL ? "None" : pwd;
}

std::string DirName(const char *pwd)
{
#define SLASH "/"
  std::string dir = pwd;
  if(dir==SLASH) return SLASH;
  auto pos = dir.rfind(SLASH);
  if(pos == std::string::npos) return "BUS?";
  return dir.substr(pos+1);
}

void MakeCommandLine(char cmd_promt[],int size)
{
  snprintf(cmd_promt,size,FORMAT,GetUserName(),GetHostName(),DirName(GetPwd()).c_str());
}

void PrintCommandPromot()
{
  char prompt[COMMAND_SIZE];
  MakeCommandLine(prompt,sizeof(prompt));
  printf("%s",prompt);
  fflush(stdout);
}

bool GetCommandLine(char *out,int size)
{
  char *c = fgets(out,size,stdin);
  if(c == NULL) return false;
  out[strlen(out)-1]=0;
  if(strlen(out)==0) return false;
  return true;
}


//3.命令行分析
bool CommandParse(char *commandline)
{
#define SEP " "
  g_argc=0;
  g_argv[g_argc++] = strtok(commandline,SEP);
  while((bool)(g_argv[g_argc++] = strtok(nullptr,SEP)));
  g_argc--;
  return true;
}
void PrintArgv()
{
  for(int i = 0;g_argv[i];i++)
  {
    printf("argv[%d]->%s\n",i,g_argv[i]);
  }
  printf("argc:%d\n",g_argc);
}

int Execute()
{
  pid_t id = fork();
  if(id==0)
  {
    execvp(g_argv[0],g_argv);
    exit(1);
  }
  pid_t rid = waitpid(id,nullptr,0);
  (void)rid;
  return 0;
}
int main()
{
  while(true)
  {
    //1.输出命令行提示符
    PrintCommandPromot();
    //2.获取用户输入的命令
    char commandline[COMMAND_SIZE];
    if(!GetCommandLine(commandline,sizeof(commandline)))
      continue;
    //printf("echo %s\n",commandline);
    //3.命令行分析
    RedirCheck();
    CommandParse(commandline);
    //PrintArgv();
    //4.执行命令
    Execute();
  }
  return 0;
}
